using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using Sherwood.Imaging.Behaviors;
using Sherwood.Imaging.Providers;

namespace Sherwood.Imaging
{
    public class Template
    {
        public static IImageProvider DefaultImageProvider { get; set; }

        static Template()
        {
            DefaultImageProvider = new UrlImageProvider(new VirtualPathSegmentProvider(1), "images");
        }

        public Template(string name)
            : this(name, DefaultImageProvider)
        {
        }

        public Template(string name, ImageOutputBehavior imageOutputBehavior)
            : this(name, DefaultImageProvider, imageOutputBehavior)
        {
        }

        /// <exception cref="ArgumentNullException"><c>imageProvider</c> or <c>imageOutputBehavior</c>is null.</exception>
        public Template(string name, IImageProvider  imageProvider) : this(name, imageProvider, new JpegImageOutputBehavior(new StaticNumberProvider(90)))
        {
        }

        /// <exception cref="ArgumentNullException"><c>imageProvider</c> or <c>imageOutputBehavior</c>is null.</exception>
        public Template(string name, IImageProvider  imageProvider, ImageOutputBehavior imageOutputBehavior)
        {
            if (imageProvider == null) throw new ArgumentNullException("imageProvider");
            if (imageOutputBehavior == null) throw new ArgumentNullException("imageOutputBehavior");

            Name = name;
            _filters = new List<IFilter>();
            this._imageProvider = imageProvider;
            this._imageOutputBehavior = imageOutputBehavior;
        }

        public string Name { get; set; }

        private readonly IImageProvider _imageProvider;
        private readonly List<IFilter> _filters;
        private readonly ImageOutputBehavior _imageOutputBehavior;

        public IList<IFilter> Filters
        {
            get { return _filters; }
        }
        
        public string ContentType
        {
            get { return _imageOutputBehavior.ContentType; }
        }

        public void SaveToStream(Stream stream)
        {
            _imageOutputBehavior.SaveToStream(GetImage(), stream);
        }

        public Image GetImage()
        {
            var image = _imageProvider.GetImage();

            foreach (var filter in _filters)
                image = filter.ApplyFilter(image);
            return image;
        }
    }
}